from tortoise.models import Model
from tortoise import fields
from enum import IntEnum
from typing import Optional


# ==================== 1. 用户管理模块 ====================

class UserStatus(IntEnum):
    """用户状态"""
    ACTIVE = 1       # 活跃
    BANNED = 2       # 封禁
    INACTIVE = 3     # 未激活


class UserRole(IntEnum):
    """用户角色"""
    USER = 1    # 普通用户
    AUTHOR = 2  # 作者
    ADMIN = 3   # 管理员


class Gender(IntEnum):
    """性别"""
    MALE = 1
    FEMALE = 2
    UNKNOWN = 3


class VipStatus(IntEnum):
    """VIP状态"""
    NORMAL = 1      # 普通用户
    VIP = 2         # VIP
    SUPER_VIP = 3   # 超级VIP


class User(Model):
    """用户表（支持用户端/创作端/管理端）"""
    id = fields.BigIntField(pk=True, description='用户ID')
    phone = fields.CharField(max_length=20, unique=True, description='手机号')
    password_hash = fields.CharField(max_length=255, null=True, description='密码哈希')
    nickname = fields.CharField(max_length=50, null=True, description='昵称')
    avatar_url = fields.CharField(max_length=500, null=True, description='头像URL')
    gender = fields.IntEnumField(Gender, null=True, description='性别')
    birthday = fields.DateField(null=True, description='生日')
    bio = fields.TextField(null=True, description='个人简介')
    role = fields.IntEnumField(UserRole, default=UserRole.USER, description='角色：user-普通用户，author-作者，admin-管理员')
    status = fields.IntEnumField(UserStatus, default=UserStatus.ACTIVE, description='状态')
    phone_verified = fields.BooleanField(default=False, description='手机验证状态')
    vip_status = fields.IntEnumField(VipStatus, default=VipStatus.NORMAL, description='VIP状态')
    vip_expires_at = fields.DatetimeField(null=True, description='VIP过期时间')
    last_login_at = fields.DatetimeField(null=True, description='最后登录时间')
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')
    updated_at = fields.DatetimeField(auto_now=True, description='更新时间')

    class Meta:
        table = "users"
        table_description = "用户表（支持用户端/创作端/管理端）"


class UserTag(Model):
    """用户标签表"""
    id = fields.IntField(pk=True, description='标签ID')
    name = fields.CharField(max_length=50, unique=True, description='标签名称')
    description = fields.TextField(null=True, description='标签描述')
    icon_url = fields.CharField(max_length=500, null=True, description='标签图标')
    created_at = fields.DatetimeField(auto_now_add=True)

    class Meta:
        table = "user_tags"
        table_description = "标签表"


class UserTagRelation(Model):
    """用户标签关联表"""
    id = fields.BigIntField(pk=True)
    user = fields.ForeignKeyField('models.User', related_name='tags', on_delete=fields.CASCADE)
    tag = fields.ForeignKeyField('models.UserTag', on_delete=fields.CASCADE)
    weight = fields.DecimalField(max_digits=3, decimal_places=2, default=1.00, description='标签权重')
    created_at = fields.DatetimeField(auto_now_add=True)

    class Meta:
        table = "user_tag_relations"
        table_description = "用户标签关联表"


class AuthorVerificationStatus(IntEnum):
    """作者认证状态"""
    PENDING = 1    # 待审核
    APPROVED = 2   # 已通过
    REJECTED = 3   # 已拒绝


class AuthorVerification(Model):
    """作者认证申请表（创作端）"""
    id = fields.BigIntField(pk=True, description='认证ID')
    user = fields.ForeignKeyField('models.User', related_name='author_verifications', on_delete=fields.CASCADE)
    real_name = fields.CharField(max_length=50, description='真实姓名')
    id_card = fields.CharField(max_length=18, description='身份证号')
    id_card_front_url = fields.CharField(max_length=500, null=True, description='身份证正面照片URL')
    id_card_back_url = fields.CharField(max_length=500, null=True, description='身份证反面照片URL')
    pen_name = fields.CharField(max_length=50, description='笔名')
    introduction = fields.TextField(null=True, description='作者简介')
    sample_work = fields.CharField(max_length=500, null=True, description='作品样例')
    status = fields.IntEnumField(AuthorVerificationStatus, default=AuthorVerificationStatus.PENDING, description='审核状态')
    reject_reason = fields.TextField(null=True, description='拒绝原因')
    verified_at = fields.DatetimeField(null=True, description='认证通过时间')
    verified_by = fields.ForeignKeyField('models.User', related_name='verified_authors', null=True, on_delete=fields.SET_NULL)
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')
    updated_at = fields.DatetimeField(auto_now=True, description='更新时间')

    class Meta:
        table = "author_verifications"
        table_description = "作者认证申请表"


class AdminRole(IntEnum):
    """管理员角色"""
    SUPER_ADMIN = 1      # 超级管理员
    CONTENT_ADMIN = 2    # 内容管理员
    USER_ADMIN = 3       # 用户管理员
    OPERATOR = 4         # 运营人员


class Admin(Model):
    """管理员表（管理端）"""
    id = fields.BigIntField(pk=True, description='管理员ID')
    user = fields.ForeignKeyField('models.User', related_name='admin_profile', on_delete=fields.CASCADE)
    username = fields.CharField(max_length=50, unique=True, description='管理员用户名')
    email = fields.CharField(max_length=100, null=True, description='邮箱')
    admin_role = fields.IntEnumField(AdminRole, default=AdminRole.OPERATOR, description='管理员角色')
    permissions = fields.JSONField(null=True, description='权限JSON（功能权限列表）')
    last_login_ip = fields.CharField(max_length=50, null=True, description='最后登录IP')
    last_login_at = fields.DatetimeField(null=True, description='最后登录时间')
    is_active = fields.BooleanField(default=True, description='是否启用')
    created_by = fields.ForeignKeyField('models.Admin', related_name='created_admins', null=True, on_delete=fields.SET_NULL)
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')
    updated_at = fields.DatetimeField(auto_now=True, description='更新时间')

    class Meta:
        table = "admins"
        table_description = "管理员表"


# ==================== 2. 小说管理模块 ====================

class NovelCategory(Model):
    """小说分类表"""
    id = fields.IntField(pk=True, description='分类ID')
    name = fields.CharField(max_length=100, description='分类名称')
    slug = fields.CharField(max_length=100, unique=True, description='URL别名')
    description = fields.TextField(null=True, description='分类描述')
    parent = fields.ForeignKeyField('models.NovelCategory', related_name='children', null=True, on_delete=fields.SET_NULL)
    level = fields.IntField(default=1, description='分类层级')
    sort_order = fields.IntField(default=0, description='排序')
    icon_url = fields.CharField(max_length=500, null=True, description='图标URL')
    novel_count = fields.IntField(default=0, description='小说数量')
    is_active = fields.BooleanField(default=True, description='是否启用')
    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)

    class Meta:
        table = "novel_categories"
        table_description = "小说分类表"


class NovelStatus(IntEnum):
    """小说状态"""
    SERIALIZING = 1  # 连载中
    COMPLETED = 2    # 已完结
    SUSPENDED = 3    # 暂停


class AuditStatus(IntEnum):
    """审核状态"""
    PENDING = 1    # 待审核
    APPROVED = 2   # 已通过
    REJECTED = 3   # 已拒绝


class Novel(Model):
    """小说表（支持创作端发布/管理端审核）"""
    id = fields.BigIntField(pk=True, description='小说ID')
    user = fields.ForeignKeyField('models.User', related_name='novels', on_delete=fields.CASCADE, description='作者ID')
    title = fields.CharField(max_length=200, description='小说标题')
    author = fields.CharField(max_length=100, description='作者笔名（冗余字段，方便搜索）')
    cover_url = fields.CharField(max_length=500, null=True, description='封面URL')
    description = fields.TextField(null=True, description='简介')
    category = fields.ForeignKeyField('models.NovelCategory', related_name='novels', description='分类ID')
    tags = fields.JSONField(null=True, description='标签JSON数组')
    status = fields.IntEnumField(NovelStatus, default=NovelStatus.SERIALIZING, description='连载状态')
    audit_status = fields.IntEnumField(AuditStatus, default=AuditStatus.PENDING, description='审核状态')
    audit_reason = fields.TextField(null=True, description='审核意见（拒绝原因）')
    audited_by = fields.ForeignKeyField('models.Admin', related_name='audited_novels', null=True, on_delete=fields.SET_NULL)
    audited_at = fields.DatetimeField(null=True, description='审核时间')
    word_count = fields.BigIntField(default=0, description='总字数')
    chapter_count = fields.IntField(default=0, description='总章数')
    view_count = fields.IntField(default=0, description='浏览次数')
    rating = fields.DecimalField(max_digits=3, decimal_places=2, default=0.00, description='评分')
    rating_count = fields.IntField(default=0, description='评分人数')
    collect_count = fields.IntField(default=0, description='收藏数')
    is_vip = fields.BooleanField(default=False, description='是否VIP')
    vip_chapter_start = fields.IntField(default=0, description='VIP章节开始位置')
    is_featured = fields.BooleanField(default=False, description='是否推荐')
    metadata = fields.JSONField(null=True, description='元数据')
    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)

    class Meta:
        table = "novels"
        table_description = "小说表（支持创作端发布/管理端审核）"


class ChapterContentType(IntEnum):
    """章节内容类型"""
    TEXT = 1    # 文本
    VIDEO = 2   # 视频
    AUDIO = 3   # 音频
    MIXED = 4   # 混合


class Chapter(Model):
    """章节表（支持创作端发布/管理端审核）"""
    id = fields.BigIntField(pk=True, description='章节ID')
    novel = fields.ForeignKeyField('models.Novel', related_name='chapters', on_delete=fields.CASCADE)
    title = fields.CharField(max_length=200, description='章节标题')
    chapter_number = fields.IntField(description='章节序号')
    content = fields.TextField(null=True, description='章节内容')
    content_type = fields.IntEnumField(ChapterContentType, default=ChapterContentType.TEXT, description='内容类型')
    word_count = fields.IntField(default=0, description='字数')
    duration_seconds = fields.IntField(default=0, description='时长（秒）')
    audit_status = fields.IntEnumField(AuditStatus, default=AuditStatus.PENDING, description='审核状态')
    audit_reason = fields.TextField(null=True, description='审核意见')
    is_vip = fields.BooleanField(default=False, description='是否VIP章节')
    view_count = fields.IntField(default=0, description='浏览次数')
    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)

    class Meta:
        table = "chapters"
        table_description = "章节表（支持创作端发布/管理端审核）"


class FileType(IntEnum):
    """文件类型"""
    VIDEO = 1
    AUDIO = 2
    IMAGE = 3
    DOCUMENT = 4


class StorageType(IntEnum):
    """存储类型"""
    LOCAL = 1
    OSS = 2
    MINIO = 3
    S3 = 4


class FileStatus(IntEnum):
    """文件状态"""
    UPLOADING = 1
    UPLOADED = 2
    PROCESSING = 3
    READY = 4
    FAILED = 5


class FileStorage(Model):
    """文件存储表"""
    id = fields.BigIntField(pk=True, description='文件ID')
    chapter = fields.ForeignKeyField('models.Chapter', related_name='files', null=True, on_delete=fields.SET_NULL)
    file_type = fields.IntEnumField(FileType, description='文件类型')
    original_name = fields.CharField(max_length=255, description='原始文件名')
    stored_name = fields.CharField(max_length=255, unique=True, description='存储文件名')
    file_path = fields.CharField(max_length=500, description='文件路径')
    file_url = fields.CharField(max_length=500, description='访问URL')
    storage_type = fields.IntEnumField(StorageType, default=StorageType.LOCAL, description='存储类型')
    file_size = fields.BigIntField(description='文件大小（字节）')
    mime_type = fields.CharField(max_length=100, description='MIME类型')
    md5_hash = fields.CharField(max_length=32, description='MD5哈希')
    duration_seconds = fields.IntField(null=True, description='时长（秒）')
    video_width = fields.IntField(null=True, description='视频宽度')
    video_height = fields.IntField(null=True, description='视频高度')
    bitrate = fields.IntField(null=True, description='比特率')
    is_cdn = fields.BooleanField(default=False, description='是否CDN加速')
    upload_user = fields.ForeignKeyField('models.User', related_name='uploaded_files', null=True, on_delete=fields.SET_NULL)
    download_count = fields.IntField(default=0, description='下载次数')
    access_count = fields.IntField(default=0, description='访问次数')
    status = fields.IntEnumField(FileStatus, default=FileStatus.UPLOADING, description='状态')
    metadata = fields.JSONField(null=True, description='元数据')
    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)

    class Meta:
        table = "file_storage"
        table_description = "文件存储表"


# ==================== 3. 书架管理模块 ====================

class ShelfType(IntEnum):
    """书架类型"""
    READING = 1    # 在读
    COMPLETED = 2  # 已读
    ON_HOLD = 3    # 待读
    DROPPED = 4    # 弃读


class Bookshelf(Model):
    """书架表"""
    id = fields.BigIntField(pk=True, description='书架ID')
    user = fields.ForeignKeyField('models.User', related_name='bookshelves', on_delete=fields.CASCADE)
    novel = fields.ForeignKeyField('models.Novel', related_name='bookshelves', on_delete=fields.CASCADE)
    shelf_name = fields.IntEnumField(ShelfType, description='书架名称')
    last_read_chapter = fields.IntField(default=0, description='最后阅读章节')
    last_read_at = fields.DatetimeField(null=True, description='最后阅读时间')
    added_at = fields.DatetimeField(auto_now_add=True, description='添加时间')

    class Meta:
        table = "bookshelves"
        table_description = "书架表"


# ==================== 4. 阅读记录模块 ====================

class ReadingProgress(Model):
    """阅读进度表"""
    id = fields.BigIntField(pk=True, description='进度ID')
    user = fields.ForeignKeyField('models.User', related_name='reading_progress', on_delete=fields.CASCADE)
    novel = fields.ForeignKeyField('models.Novel', related_name='reading_progress', on_delete=fields.CASCADE)
    chapter = fields.ForeignKeyField('models.Chapter', related_name='reading_progress', on_delete=fields.CASCADE)
    read_position = fields.IntField(default=0, description='阅读位置（字符数）')
    read_percentage = fields.DecimalField(max_digits=5, decimal_places=2, default=0.00, description='阅读百分比')
    last_read_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)

    class Meta:
        table = "reading_progress"
        table_description = "阅读进度表"


class ReadingHistory(Model):
    """阅读历史表"""
    id = fields.BigIntField(pk=True, description='历史ID')
    user = fields.ForeignKeyField('models.User', related_name='reading_history', on_delete=fields.CASCADE)
    novel = fields.ForeignKeyField('models.Novel', related_name='reading_history', on_delete=fields.CASCADE)
    chapter = fields.ForeignKeyField('models.Chapter', related_name='reading_history', on_delete=fields.CASCADE)
    read_at = fields.DatetimeField(auto_now_add=True, description='阅读时间')
    read_duration = fields.IntField(default=0, description='阅读时长（秒）')

    class Meta:
        table = "reading_history"
        table_description = "阅读历史表"


# ==================== 5. 互动模块 ====================

class TargetType(IntEnum):
    """目标类型"""
    NOVEL = 1
    REVIEW = 2
    COMMENT = 3


class Like(Model):
    """点赞表"""
    id = fields.BigIntField(pk=True, description='点赞ID')
    user = fields.ForeignKeyField('models.User', related_name='likes', on_delete=fields.CASCADE)
    target_type = fields.IntEnumField(TargetType, description='点赞类型')
    target_id = fields.BigIntField(description='目标ID')
    created_at = fields.DatetimeField(auto_now_add=True)

    class Meta:
        table = "likes"
        table_description = "点赞表"


class CommentTargetType(IntEnum):
    """评论目标类型"""
    NOVEL = 1
    CHAPTER = 2


class CommentStatus(IntEnum):
    """评论状态"""
    ACTIVE = 1
    DELETED = 2


class Comment(Model):
    """评论表"""
    id = fields.BigIntField(pk=True, description='评论ID')
    user = fields.ForeignKeyField('models.User', related_name='comments', on_delete=fields.CASCADE)
    target_type = fields.IntEnumField(CommentTargetType, description='评论类型')
    target_id = fields.BigIntField(description='目标ID')
    parent = fields.ForeignKeyField('models.Comment', related_name='replies', null=True, on_delete=fields.CASCADE)
    content = fields.TextField(description='评论内容')
    is_anonymous = fields.BooleanField(default=False, description='是否匿名')
    helpful_count = fields.IntField(default=0, description='有用数')
    reply_count = fields.IntField(default=0, description='回复数')
    status = fields.IntEnumField(CommentStatus, default=CommentStatus.ACTIVE, description='状态')
    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)

    class Meta:
        table = "comments"
        table_description = "评论表"


class ReviewStatus(IntEnum):
    """评价状态"""
    PENDING = 1
    APPROVED = 2
    REJECTED = 3


class NovelReview(Model):
    """小说评价表"""
    id = fields.BigIntField(pk=True, description='评价ID')
    user = fields.ForeignKeyField('models.User', related_name='reviews', on_delete=fields.CASCADE)
    novel = fields.ForeignKeyField('models.Novel', related_name='reviews', on_delete=fields.CASCADE)
    rating = fields.IntField(description='评分（1-5）')
    content = fields.TextField(null=True, description='评价内容')
    is_verified = fields.BooleanField(default=False, description='是否验证购买')
    helpful_count = fields.IntField(default=0, description='有用数')
    reply_count = fields.IntField(default=0, description='回复数')
    status = fields.IntEnumField(ReviewStatus, default=ReviewStatus.PENDING, description='状态')
    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)

    class Meta:
        table = "novel_reviews"
        table_description = "小说评价表"


# ==================== 6. 搜索统计模块 ====================

class SearchHistory(Model):
    """搜索历史表"""
    id = fields.BigIntField(pk=True, description='历史ID')
    user = fields.ForeignKeyField('models.User', related_name='search_history', null=True, on_delete=fields.SET_NULL)
    keyword = fields.CharField(max_length=200, description='搜索关键词')
    search_count = fields.IntField(default=1, description='搜索次数')
    last_searched_at = fields.DatetimeField(auto_now_add=True, description='最后搜索时间')

    class Meta:
        table = "search_history"
        table_description = "搜索历史表"


# ==================== 7. 系统管理模块 ====================

class OperationLogStatus(IntEnum):
    """操作日志状态"""
    SUCCESS = 1
    ERROR = 2
    WARNING = 3


class OperationLog(Model):
    """操作日志表"""
    id = fields.BigIntField(pk=True, description='日志ID')
    user = fields.ForeignKeyField('models.User', related_name='operation_logs', null=True, on_delete=fields.SET_NULL)
    operation_type = fields.CharField(max_length=50, description='操作类型')
    operation_module = fields.CharField(max_length=50, description='操作模块')
    operation_description = fields.TextField(null=True, description='操作描述')
    request_ip = fields.CharField(max_length=50, null=True, description='请求IP')
    request_data = fields.JSONField(null=True, description='请求数据')
    response_data = fields.JSONField(null=True, description='响应数据')
    execution_time = fields.IntField(null=True, description='执行时间（毫秒）')
    status = fields.IntEnumField(OperationLogStatus, default=OperationLogStatus.SUCCESS, description='状态')
    error_message = fields.TextField(null=True, description='错误信息')
    created_at = fields.DatetimeField(auto_now_add=True)

    class Meta:
        table = "operation_logs"
        table_description = "操作日志表"


# ==================== 8. VIP支付模块 ====================

class OrderType(IntEnum):
    """订单类型"""
    VIP = 1
    NOVEL = 2


class PaymentStatus(IntEnum):
    """支付状态"""
    PENDING = 1
    PAID = 2
    FAILED = 3
    REFUNDED = 4


class Order(Model):
    """订单表"""
    id = fields.BigIntField(pk=True, description='订单ID')
    order_no = fields.CharField(max_length=50, unique=True, description='订单号')
    user = fields.ForeignKeyField('models.User', related_name='orders', on_delete=fields.CASCADE)
    order_type = fields.IntEnumField(OrderType, description='订单类型')
    amount = fields.DecimalField(max_digits=10, decimal_places=2, description='订单金额')
    payment_status = fields.IntEnumField(PaymentStatus, default=PaymentStatus.PENDING, description='支付状态')
    payment_method = fields.CharField(max_length=50, null=True, description='支付方式')
    payment_id = fields.CharField(max_length=100, null=True, description='支付平台订单ID')
    paid_at = fields.DatetimeField(null=True, description='支付时间')
    expires_at = fields.DatetimeField(null=True, description='订单过期时间')
    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)

    class Meta:
        table = "orders"
        table_description = "订单表"


# ==================== 9. RBAC权限管理模块 ====================

class Role(Model):
    """角色表"""
    id = fields.IntField(pk=True, description='角色ID')
    name = fields.CharField(max_length=50, unique=True, description='角色名称')
    code = fields.CharField(max_length=50, unique=True, description='角色代码，如：user, author, admin')
    description = fields.CharField(max_length=200, null=True, description='角色描述')
    is_active = fields.BooleanField(default=True, description='是否启用')
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')
    updated_at = fields.DatetimeField(auto_now=True, description='更新时间')

    class Meta:
        table = "roles"
        table_description = "角色表"


class Permission(Model):
    """权限表"""
    id = fields.IntField(pk=True, description='权限ID')
    name = fields.CharField(max_length=100, description='权限名称')
    code = fields.CharField(max_length=100, unique=True, description='权限代码，如：novel:create, novel:update')
    module = fields.CharField(max_length=50, description='权限模块，如：novel, chapter, user')
    description = fields.CharField(max_length=200, null=True, description='权限描述')
    is_active = fields.BooleanField(default=True, description='是否启用')
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')

    class Meta:
        table = "permissions"
        table_description = "权限表"


class UserRoleRelation(Model):
    """用户角色关联表（多对多）"""
    id = fields.BigIntField(pk=True)
    user = fields.ForeignKeyField('models.User', related_name='user_roles', on_delete=fields.CASCADE, description='用户ID')
    role = fields.ForeignKeyField('models.Role', related_name='user_roles', on_delete=fields.CASCADE, description='角色ID')
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')

    class Meta:
        table = "user_role_relations"
        table_description = "用户角色关联表"
        unique_together = ("user", "role")


class RolePermissionRelation(Model):
    """角色权限关联表（多对多）"""
    id = fields.BigIntField(pk=True)
    role = fields.ForeignKeyField('models.Role', related_name='role_permissions', on_delete=fields.CASCADE, description='角色ID')
    permission = fields.ForeignKeyField('models.Permission', related_name='role_permissions', on_delete=fields.CASCADE, description='权限ID')
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')

    class Meta:
        table = "role_permission_relations"
        table_description = "角色权限关联表"
        unique_together = ("role", "permission")